"""
项目相关模型
"""
from datetime import datetime, date
from sqlalchemy.orm import relationship
from .base import BaseModel, get_db

class Project(BaseModel):
    """项目模型"""
    __tablename__ = 'project'
    
    # 基本信息
    name = get_db().Column(get_db().String(200), nullable=False)
    description = get_db().Column(get_db().Text)
    start_date = get_db().Column(get_db().DateTime)
    end_date = get_db().Column(get_db().DateTime)
    status = get_db().Column(get_db().String(50), default='未开始')  # 未开始, 进行中, 已完成, 已延期
    progress = get_db().Column(get_db().Integer, default=0)  # 0-100
    
    # 关联人员
    manager_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'))
    sales_manager_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'))  # 销售负责人ID
    customer_id = get_db().Column(get_db().Integer, get_db().ForeignKey('customer.id'))  # 关联客户ID
    
    # 项目属性
    project_type = get_db().Column(get_db().String(50), default='产品研发')  # 产品研发, 产品设计, 工程项目, 软件交付等
    project_source = get_db().Column(get_db().String(50), default='公开招标')  # 公开招标, 广告营销, 客户介绍, 朋友介绍, 公司资源, 销售自拓等
    project_number = get_db().Column(get_db().String(50))  # 项目编号
    project_code = get_db().Column(get_db().String(50))  # 项目编码
    budget = get_db().Column(get_db().Float, default=0.0)  # 项目预算
    risk_level = get_db().Column(get_db().String(20), default='低')  # 风险等级：低、中、高
    
    # 关联关系
    manager = relationship('User', foreign_keys=[manager_id], backref='managed_projects')
    sales_manager = relationship('User', foreign_keys=[sales_manager_id], backref='sales_managed_projects')
    customer = relationship('Customer', foreign_keys=[customer_id])
    
    # 项目任务
    tasks = relationship('ProjectTask', backref='project', lazy=True, cascade='all, delete-orphan')
    # 项目里程碑
    milestones = relationship('ProjectMilestone', backref='project', lazy=True, cascade='all, delete-orphan')
    # 项目成本
    costs = relationship('ProjectCost', backref='project', lazy=True, cascade='all, delete-orphan')
    # 项目角色
    roles = relationship('ProjectRole', backref='project', lazy=True, cascade='all, delete-orphan')
    # 项目操作日志
    logs = relationship('ProjectLog', backref='project', lazy=True, cascade='all, delete-orphan')
    # 周报
    weekly_reports = relationship('WeeklyReport', backref='project')

class ProjectTask(BaseModel):
    """项目任务模型"""
    __tablename__ = 'project_task'
    
    # 基本信息
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    name = get_db().Column(get_db().String(200), nullable=False)
    description = get_db().Column(get_db().Text)
    status = get_db().Column(get_db().String(50), default='未开始')  # 未开始, 进行中, 已完成
    priority = get_db().Column(get_db().String(20), default='中')  # 低, 中, 高
    progress = get_db().Column(get_db().Integer, default=0)  # 0-100
    
    # 时间信息
    start_date = get_db().Column(get_db().DateTime)
    end_date = get_db().Column(get_db().DateTime)
    
    # 人员信息
    assignee_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'))
    creator_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'))  # 创建者ID
    assigner_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'))  # 分配者ID
    
    # 任务层级
    parent_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'))  # 父任务ID，支持多级任务
    
    # 任务属性
    work_hour = get_db().Column(get_db().Float, default=0.0)  # 工时
    task_code = get_db().Column(get_db().String(50))  # 任务编码
    milestone_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_milestone.id'))  # 关联的里程碑ID
    
    # 关联关系
    assignee = relationship('User', foreign_keys=[assignee_id])
    creator = relationship('User', foreign_keys=[creator_id], backref='created_tasks')
    assigner = relationship('User', foreign_keys=[assigner_id], backref='assigned_by_me')
    parent = relationship('ProjectTask', remote_side='ProjectTask.id', backref='subtasks')  # 自反关系
    milestone = relationship('ProjectMilestone', backref='tasks')  # 关联的里程碑
    
    # 任务依赖
    dependencies = relationship('TaskDependency', foreign_keys='TaskDependency.task_id', backref='main_task', lazy='dynamic')
    depended_by = relationship('TaskDependency', foreign_keys='TaskDependency.depends_on_id', backref='depends_on_task', lazy='dynamic')
    
    # 任务成本
    costs = relationship('ProjectCost', backref='related_task', lazy=True, cascade='all, delete-orphan')
    
    # 任务关注
    followers = relationship('TaskFollow', backref='task_followers', lazy=True, cascade='all, delete-orphan', overlaps="followed_tasks")
    
    # 任务评审
    reviews = relationship('TaskReview', foreign_keys='TaskReview.task_id', lazy=True, cascade='all, delete-orphan', backref='task_reviews')
    
    # 工时记录
    work_hours = relationship('WorkHour', backref='task', lazy=True, cascade='all, delete-orphan')
    
    def update_milestone(self):
        """更新关联的里程碑状态和进度"""
        if self.milestone_id:
            from .project import ProjectMilestone
            milestone = ProjectMilestone.query.get(self.milestone_id)
            if milestone:
                milestone.calculate_progress()
                milestone.update_status()
    
    def set_status(self, new_status):
        """设置任务状态并更新关联的里程碑"""
        old_status = self.status
        self.status = new_status
        
        # 根据状态自动更新进度
        if new_status == '未开始':
            self.progress = 0
        elif new_status == '进行中':
            # 如果进度为0，设置为10%
            if self.progress == 0:
                self.progress = 10
        elif new_status == '已完成':
            self.progress = 100
        
        get_db().session.commit()
        
        # 如果状态发生变化，更新关联的里程碑
        if old_status != new_status:
            self.update_milestone()
    
    def set_progress(self, new_progress):
        """设置任务进度并更新关联的里程碑"""
        self.progress = new_progress
        
        # 根据进度自动更新状态
        if new_progress == 0:
            self.status = '未开始'
        elif new_progress == 100:
            self.status = '已完成'
        elif 0 < new_progress < 100:
            self.status = '进行中'
        
        get_db().session.commit()
        
        # 更新关联的里程碑
        self.update_milestone()

class ProjectMilestone(BaseModel):
    """项目里程碑模型"""
    __tablename__ = 'project_milestone'
    
    # 基本信息
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    name = get_db().Column(get_db().String(200), nullable=False)
    description = get_db().Column(get_db().Text)
    
    # 时间信息
    start_date = get_db().Column(get_db().Date)  # 里程碑开始日期
    due_date = get_db().Column(get_db().Date, nullable=False)
    
    # 状态信息
    status = get_db().Column(get_db().String(20), default='未开始')  # 未开始、已完成、已延期
    progress = get_db().Column(get_db().Integer, default=0)  # 里程碑进度，0-100
    
    def calculate_progress(self):
        """根据关联的任务计算里程碑进度"""
        if not self.tasks:
            return 0
        
        # 获取所有关联的任务
        from .project import ProjectTask
        tasks = ProjectTask.query.filter_by(milestone_id=self.id).all()
        if not tasks:
            return 0
        
        # 计算所有任务的进度平均值
        total_progress = sum(task.progress for task in tasks)
        average_progress = total_progress // len(tasks)
        
        # 更新里程碑进度
        self.progress = average_progress
        get_db().session.commit()
        
        return average_progress
    
    def update_status(self):
        """根据任务状态更新里程碑状态"""
        if not self.tasks:
            return
        
        # 获取所有关联的任务
        from .project import ProjectTask
        tasks = ProjectTask.query.filter_by(milestone_id=self.id).all()
        if not tasks:
            return
        
        # 统计任务状态
        completed_count = sum(1 for task in tasks if task.status == '已完成')
        in_progress_count = sum(1 for task in tasks if task.status == '进行中')
        total_count = len(tasks)
        
        # 根据任务状态更新里程碑状态
        if completed_count == total_count:
            self.status = '已完成'
        elif in_progress_count > 0:
            self.status = '进行中'
        else:
            self.status = '未开始'
        
        # 检查是否延期
        if self.due_date and datetime.now().date() > self.due_date and self.status != '已完成':
            self.status = '已延期'
        
        get_db().session.commit()

class TaskDependency(BaseModel):
    """任务依赖模型"""
    __tablename__ = 'task_dependency'
    
    task_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'), nullable=False)
    depends_on_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'), nullable=False)
    dependency_type = get_db().Column(get_db().String(20), default='finish_to_start')  # finish_to_start, start_to_start, finish_to_finish, start_to_finish

class ProjectCost(BaseModel):
    """项目成本模型"""
    __tablename__ = 'project_cost'
    
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    task_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'))
    cost_type = get_db().Column(get_db().String(50), nullable=False)  # 人工成本、材料成本、设备成本等
    amount = get_db().Column(get_db().Float, nullable=False)
    description = get_db().Column(get_db().Text)
    record_date = get_db().Column(get_db().Date, nullable=False)

class ProjectRole(BaseModel):
    """项目角色模型"""
    __tablename__ = 'project_role'
    
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    user_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'), nullable=False)
    role = get_db().Column(get_db().String(50), nullable=False)  # 项目经理、开发人员、测试人员等
    department = get_db().Column(get_db().String(100))  # 部门
    position = get_db().Column(get_db().String(100))  # 职位
    
    # 关联关系
    user = relationship('User', backref='project_roles')

class ProjectLog(BaseModel):
    """项目操作日志模型"""
    __tablename__ = 'project_log'
    
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    operation_type = get_db().Column(get_db().String(50), nullable=False)  # 操作类型：创建、更新、删除等
    operation_content = get_db().Column(get_db().Text)  # 操作内容
    operator_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'), nullable=False)
    
    # 关联关系
    operator = relationship('User', foreign_keys=[operator_id])

class WeeklyReport(BaseModel):
    """周报模型"""
    __tablename__ = 'weekly_report'
    
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    user_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'), nullable=False)
    week_start_date = get_db().Column(get_db().Date, nullable=False)  # 周开始日期（周一）
    week_end_date = get_db().Column(get_db().Date, nullable=False)  # 周结束日期（周日）
    weekly_work_hours = get_db().Column(get_db().Float, default=0)  # 本周总工时
    weekly_work_content = get_db().Column(get_db().Text)  # 本周工作内容
    next_week_plan = get_db().Column(get_db().Text)  # 下周工作计划
    weekly_issues = get_db().Column(get_db().Text)  # 本周遇到的问题

class TaskFollow(BaseModel):
    """任务关注模型"""
    __tablename__ = 'task_follow'
    
    user_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'), nullable=False)
    task_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'), nullable=False)
    follow_time = get_db().Column(get_db().DateTime, default=datetime.now)
    
    # 关联关系
    user = relationship('User', backref='user_followed_tasks')
    task_ref = relationship('ProjectTask', backref='task_followers', overlaps="followers,task_followers")

class TaskReview(BaseModel):
    """任务评审模型"""
    __tablename__ = 'task_review'
    
    task_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'), nullable=False)
    reviewer_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'), nullable=False)
    status = get_db().Column(get_db().String(50), default='待评审')  # 待评审、已通过、已拒绝
    review_time = get_db().Column(get_db().DateTime)
    comments = get_db().Column(get_db().Text)
    
    # 关联关系
    reviewer = relationship('User', backref='reviews')
    task = relationship('ProjectTask', overlaps="reviews,task_reviews")

class WorkHour(BaseModel):
    """工时记录模型"""
    __tablename__ = 'work_hour'
    
    task_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project_task.id'), nullable=False)
    user_id = get_db().Column(get_db().Integer, get_db().ForeignKey('user.id'), nullable=False)
    project_id = get_db().Column(get_db().Integer, get_db().ForeignKey('project.id'), nullable=False)
    work_hours = get_db().Column(get_db().Float, nullable=False)  # 工时数
    work_date = get_db().Column(get_db().Date, nullable=False)  # 工作日期
    start_time = get_db().Column(get_db().Time, nullable=True)  # 工作开始时间
    end_time = get_db().Column(get_db().Time, nullable=True)  # 工作结束时间
    description = get_db().Column(get_db().Text)  # 工作内容描述
    
    # 关联关系
    user = relationship('User', foreign_keys=[user_id])
    project = relationship('Project', foreign_keys=[project_id])